package org.daochong.fastdev;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import org.daochong.lang.AbstractContext;
import org.daochong.lang.BeanUtil;
import org.daochong.lang.JdbcTemplateProvider;
import org.daochong.lang.ObjectArrayList;
import org.daochong.lang.Properties;
import org.daochong.lang.uai.UniteAccessInterfaceFactory;

public class Context extends AbstractContext {

	private static final long serialVersionUID = 1L;

	private String operType;

	private String operData;

	private String operPath;

	private Object source;

	private Properties config;

	private Map<String, Object> returnObjects;

	private String view;

	private boolean success = true;

	private List<Throwable> exceptions;

	private IClassMappingFactory classMappingFactory;

	private UniteAccessInterfaceFactory uaiFactory;

	private JdbcTemplateProvider jdbcTemplateProvider;

	private Properties currentConfig;

	private IExecutor executor;

	private Stack<Boolean> conditions;

	private Stack<Boolean> conditionFind;
	
	private boolean end;

	public boolean isEnd() {
		return end;
	}

	public void setEnd(boolean end) {
		this.end = end;
	}

	public String getOperPath() {
		return operPath;
	}

	public void setOperPath(String operPath) {
		this.operPath = operPath;
	}

	public boolean isCondition() {
		return !conditions.isEmpty();
	}

	public boolean getConditionCurrent() {
		return this.conditions.peek();
	}

	public void addCondition(boolean condition) {
		this.conditions.push(condition);
		this.conditionFind.push(condition);
	}

	public void setCondition(boolean condition) {
		this.conditions.pop();
		this.conditions.push(condition);
		if (condition) {
			this.conditionFind.pop();
			this.conditionFind.push(true);
		}
	}

	public boolean getConditionElse() {
		return !this.conditionFind.peek();
	}

	public boolean endCondition() {
		boolean re = this.conditions.pop();
		this.conditionFind.pop();
		return re;
	}

	public Context() {
		super();
		this.returnObjects = new LinkedHashMap<String, Object>();
		this.conditions = new Stack<Boolean>();
		this.conditionFind = new Stack<Boolean>();
	}

	public void add(OperationId oid, Object obj) {
		String id = oid.getId();
		if(id.indexOf(".")>0){
			id = BeanUtil.toBeanString(id);
		}
		this.addAttribute(id, obj);
		if (!oid.isIgnore()) {
			this.add(id, obj);
		}
	}

	public void add(String id, Object obj) {
		Object o = this.returnObjects.get(id);
		if (o != null) {
			ObjectArrayList list;
			if (o instanceof ObjectArrayList) {
				list = (ObjectArrayList) o;
			} else {
				list = new ObjectArrayList();
				list.add(o);
			}
			list.add(obj);
			this.returnObjects.put(id, list);
		} else {
			this.returnObjects.put(id, obj);
		}
	}

	public void addException(Throwable e) {
		if (this.exceptions == null) {
			this.exceptions = new ArrayList<Throwable>();
		}
		this.exceptions.add(e);
	}

	public void clear() {
		this.returnObjects.clear();
	}

	@Override
	public <T> T getBean(Class<T> clazz) {
		return this.getExecutor().getBean(clazz);
	}

	@Override
	public Object getBean(String name) {
		return this.getExecutor().getBean(name);
	}

	public IClassMappingFactory getClassMappingFactory() {
		return classMappingFactory;
	}

	public Properties getConfig() {
		return config;
	}

	public Properties getCurrentConfig() {
		return currentConfig;
	}

	public List<Throwable> getExceptions() {
		return exceptions;
	}

	public IExecutor getExecutor() {
		return executor;
	}

	public JdbcOperations getJdbcOperations() {
		return getJdbcOperations(getCurrentConfig());
	}

	public JdbcOperations getJdbcOperations(Properties config) {
		return getJdbcOperations(config.getProperty("jdbc.configId"), config.getProperty("jdbc.groupId"));
	}

	public JdbcOperations getJdbcOperations(String configId, String groupId) {
		DefaultJdbcOperations jo = new DefaultJdbcOperations();
		if (configId == null) {
			jo.setJdbc(this.getJdbcTemplateProvider().requestJdbcTempalte());
		} else {
			if (groupId == null) {
				jo.setJdbc(this.getJdbcTemplateProvider().requestJdbcTempalte(configId));
			} else {
				jo.setJdbc(this.getJdbcTemplateProvider().requestJdbcTempalte(configId, groupId));
			}
		}
		return jo;
	}

	public JdbcTemplateProvider getJdbcTemplateProvider() {
		return jdbcTemplateProvider;
	}

	public JpaOperations getJpaOperations() {
		return getJpaOperations(this.getCurrentConfig());
	}

	public JpaOperations getJpaOperations(Properties config) {
		return getJpaOperations(config.getProperty("jdbc.configId"), config.getProperty("jdbc.groupId"));
	}

	public JpaOperations getJpaOperations(String configId, String groupId) {
		DefaultJpaOperations jo = new DefaultJpaOperations();
		if (configId == null) {
			jo.setJdbc(this.getJdbcTemplateProvider().requestJdbcTempalte());
		} else {
			if (groupId == null) {
				jo.setJdbc(this.getJdbcTemplateProvider().requestJdbcTempalte(configId));
			} else {
				jo.setJdbc(this.getJdbcTemplateProvider().requestJdbcTempalte(configId, groupId));
			}
		}
		return jo;
	}

	public String getOperType() {
		return operType;
	}

	public Map<String, Object> getReturnObjects() {
		return returnObjects;
	}

	public Object getSource() {
		return source;
	}

	public UniteAccessInterfaceFactory getUaiFactory() {
		return uaiFactory;
	}

	public String getView() {
		return view;
	}

	public boolean isSuccess() {
		return success;
	}

	public Set<String> keys() {
		return this.returnObjects.keySet();
	}

	public void remove(String id) {
		this.returnObjects.remove(id);
	}

	public void setClassMappingFactory(IClassMappingFactory classMappingFactory) {
		this.classMappingFactory = classMappingFactory;
	}

	public void setConfig(Properties config) {
		this.config = config;
	}

	public void setCurrentConfig(Properties currentConfig) {
		this.currentConfig = currentConfig;
	}

	public void setExceptions(List<Throwable> exceptions) {
		this.exceptions = exceptions;
	}

	public void setExecutor(IExecutor executor) {
		this.executor = executor;
	}

	public void setJdbcTemplateProvider(JdbcTemplateProvider jdbcTemplateProvider) {
		this.jdbcTemplateProvider = jdbcTemplateProvider;
	}

	public String getOperData() {
		return operData;
	}

	public void setOperData(String operData) {
		this.operData = operData;
	}

	public void setOperType(String operType) {
		this.operType = operType;
	}

	public void setSource(Object source) {
		this.source = source;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public void setUaiFactory(UniteAccessInterfaceFactory uaiFactory) {
		this.uaiFactory = uaiFactory;
	}

	public void setView(String view) {
		this.view = view;
	}

	public void update(String id, Object obj) {
		this.returnObjects.put(id, obj);
	}

}
